package top.xia17.plugins.fast.user.password;

import top.xia17.plugins.fast.common.exceptions.BadConfigException;
import top.xia17.plugins.fast.common.spring.SpringContextHolder;
import lombok.extern.slf4j.Slf4j;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * 密码生成器管理
 *
 * @author xia17
 * @date 2022/2/18
 */
@Slf4j
public class PasswordGeneratorManager {

    /**
     * 密码相关的配置
     */
    private final PasswordGeneratorProperties passwordGeneratorProperties;

    /**
     * 默认的密码生成器
     */
    private PasswordGenerator defaultPasswordGenerate;


    /**
     * 存储已经初始化好的发射器
     */
    private final Map<String, PasswordGenerator> generatorMap = new HashMap<>(6);

    public PasswordGeneratorManager(PasswordGeneratorProperties passwordGeneratorProperties) {
        this.passwordGeneratorProperties = passwordGeneratorProperties;
    }

    /**
     * 生成密码
     * 使用默认的密码生成器生成密码
     *
     * @param password 用户填写的密码
     * @return /
     */
    public String generate(String password){
        if (defaultPasswordGenerate == null){
            defaultPasswordGenerate =
                    this.obtainPasswordGeneratorOrElseThrow(passwordGeneratorProperties.getDefaultGenerator());
        }
        return defaultPasswordGenerate.generate(password);
    }

    /**
     * 生成密码
     * @param generatorId 密码生成器
     * @param password 密码
     * @return /
     */
    public String generate(String generatorId, String password){
        PasswordGenerator passwordGenerator = this.obtainPasswordGeneratorOrElseThrow(generatorId);
        return passwordGenerator.generate(password);
    }


    /**
     * 从容器中获取密码生成器
     * @param id /
     * @return /
     */
    public Optional<PasswordGenerator> obtainPasswordGenerator(String id) {
        PasswordGenerator generator = generatorMap.get(id);
        if (generator == null) {
            synchronized (this) {
                generator = generatorMap.get(id);
                if (generator != null) {
                    return Optional.of(generator);
                }
                // 从容器中获取
                Collection<PasswordGenerator> beans = SpringContextHolder.getBeans(PasswordGenerator.class);
                Optional<PasswordGenerator> optional = beans.stream().filter(e -> e.getId().equals(id)).findFirst();
                // 初始化密码生成器
                optional.ifPresent(this::initPasswordGenerator);
                return optional;
            }
        }
        return Optional.of(generator);
    }

    /**
     * 从容器中获取密码生成器,如果不存在抛出异常
     * @param id /
     * @return /
     */
    public PasswordGenerator obtainPasswordGeneratorOrElseThrow(String id){
        return obtainPasswordGenerator(id).orElseThrow(() -> new BadConfigException("没有找到id为" + id + "的密码生成器"));
    }

    /**
     * 初始化密码生成器
     * @param passwordGenerator 密码生成器
     */
    public void initPasswordGenerator(PasswordGenerator passwordGenerator){
        Map<String, String> properties = passwordGeneratorProperties.getGeneratorProperties().get(passwordGenerator.getId());
        passwordGenerator.setProperties(properties);
        this.generatorMap.put(passwordGenerator.getId(), passwordGenerator);
    }

}
